import inspect
import sys,os,time
p=os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
p=os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(p))))
p=p+os.sep+'_base_tool'+os.sep+'python'
sys.path.append(p)
from base_class1_0 import base_class # type: ignore
import tornado.ioloop  
import tornado.web  
import json as JSON
import socket
#快速查找 注册了100w条path,匹配一条path的时间在0s左右
class a_1_0_2_0_0_fast_find:
    def __init__(self,bind_func=None):
        self.bind_func=bind_func
        self.fast_dict={}#快速搜索字典
    #添加路径
    def add(self,**kwargs):
        """
        path:路径 如/eee/eer/#
        info:{"path":path,"handle":func} func是执行的回调函数
        """
        path=kwargs.get("path")
        if self.bind_func is not None:
            self.bind_func(path)
        new_dct=self.fast_dict
        for i in path:
            new_dct2=new_dct.get(i)
            if new_dct2 is None:
                new_dct[i]={}
                new_dct=new_dct[i]
            else:
                new_dct=new_dct2
        new_dct['value']=kwargs 
        print("绑定path:",path)
        print("当前:",self.fast_dict)
    #查找路径
    def find(self,path):
        match_path=''
        now_dict=self.fast_dict
        for i in path:
            # print('find',i,topics)
            if '#'in now_dict:
                return {"match_path":match_path+'#',"info":now_dict['#']['value']}
            else:
                match_path+=i
                now_dict=now_dict.get(i)
                if now_dict is None:return#没有匹配到
        if now_dict.get('value'):return {"match_path":match_path,"info":now_dict['value']}
        elif now_dict.get('#')is not None:return {"match_path":match_path+'#',"info":now_dict['#']['value']}
        else:return None#没有匹配到
    def handle(self,path,data):
        now_info=self.find(path)#查找topic
        print('开始匹配：',self.fast_dict)
        print('匹配到:',now_info)
        #如果对topic进行处理
        if now_info is not None:
            # print("匹配到path:",path)
            # print("\t\t数据:",data)   
            #执行对应topic的handle函数
            now_info['info']['handle'](data=data,path=path)
class a_1_0_2_0_0_tornado_server(tornado.web.RequestHandler):
    temp_obj=None
    def prepare(self):
        self.head_params=self.request.arguments
        self.body_json = self.body_params=None
        try:
            self.body_json = self.body_params=self.request.body
            while not isinstance(self.body_json,dict):
                self.body_json =JSON.loads(self.body_json)
        except ValueError:
            self.body_json = {'error':'不是json格式'}
    def get(self,p):
        print("开始匹配",self.request.uri)
        # print("fast_obj",id(self.temp_obj._all_obj['1'].fast_find_obj['get'].fast_dict))
        self.temp_obj.fast_find_obj['get'].handle(path=self.request.uri.split("?")[0],data=self)
    def post(self,p):
        self.temp_obj.fast_find_obj['post'].handle(path=self.request.uri.split("?")[0],data=self)
    def put(self,p):
        self.temp_obj.fast_find_obj['put'].handle(path=self.request.uri.split("?")[0],data=self)
    def delete(self,p):
        self.temp_obj.fast_find_obj['delete'].handle(path=self.request.uri.split("?")[0],data=self)
class a_1_0_2_0_0(base_class):
    def get_external_ip(self):  
        # 尝试获取网络接口上绑定的、可以从网络访问的IP地址  
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  
        try:  
            # 不需要真正发送数据，只是获取本地主机名  
            s.connect(('8.8.8.8', 1))  # 连接到Google的公共DNS服务器  
            ip_address = s.getsockname()[0]  
        except Exception:  
            ip_address = socket.gethostbyname(socket.gethostname())  # 如果失败，则使用本地主机名  
        finally:  
            s.close()  
        return ip_address  
    def get_dir_path(self,path_,n):
        while n:
            n-=1
            path_=os.path.dirname(path_)
        return path_
    def run_server(self):
        http_port=self.kwargs.get("http_port")
        http_host=self.kwargs.get("http_host")
        self.recv_port=self.kwargs.get('recv_port')
        self.recv_ip=self.kwargs.get('recv_ip')
        #为tornado处理类添加类对象 将组件作为参数传递进去
        #创建url快速匹配对象
        self.fast_find_obj={
            "post":a_1_0_2_0_0_fast_find(),
            "put":a_1_0_2_0_0_fast_find(),
            "get":a_1_0_2_0_0_fast_find(),
            "delete":a_1_0_2_0_0_fast_find()
        }
        a_1_0_2_0_0_tornado_server.temp_obj=self
        app = tornado.web.Application([
            (r"/static_base/(.*)", tornado.web.StaticFileHandler, {"path":self.get_dir_path(self._run_dir,10)+os.sep+"easy_edit"+os.sep+"_static_dir"}),
            (r"/(.*)", a_1_0_2_0_0_tornado_server),
            
        ])  
        print("http服务开始启动")
        self.http_obj=(self._temp_id,self._process_id,self.recv_port)
        self.out_params={"http_obj":self.http_obj,"进程通信端口":self.recv_port}
        self.out(self.out_params)
        print("http服务传参结束开始监听...")
        ip_address=self.get_external_ip()
        print(f"服务访问网址为:http://{ip_address}:{http_port}") 
        app.listen(port=http_port,address=http_host)  
        self._recv_thread(2)#两秒后运行接收数据的socket
        tornado.ioloop.IOLoop.current().start()
    
    def run(self,**kwargs):
        self.http_obj=(self._temp_id,self._process_id,self.recv_port)
        self.out_params={"http_obj":self.http_obj,"进程通信端口":self.recv_port}
        return self.out_params

if __name__=="__main__":
    pass